package ch.zhaw.skuh.turing.view;

import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Label;
import java.awt.Panel;

import ch.zhaw.skuh.turing.controller.Factory;
import ch.zhaw.skuh.turing.model.turingmaschine.TuringChar;

public class MaschinePanel extends Panel {
	/**
	 * 
	 */
	private static final long serialVersionUID = 3540411182483585449L;
	GridBagLayout gLayout;
	GridBagConstraints gConstraints;

	private Label head;
	private Label[][] tapeLabels;
	private int offset;
	private int tapeCount;
	private TuringChar turingChar;

	public MaschinePanel(TuringChar tc) {
		this.turingChar = tc;
		
		this.offset = Factory.OFFSET;
		this.tapeCount = turingChar.getTapeCount();
		this.tapeLabels = new Label[tapeCount][2 * offset + 1];
		gLayout = new GridBagLayout();
		gConstraints = new GridBagConstraints();
		gConstraints.weightx = 1.0;

		setLayout(gLayout);

		Label label;

		// gridwith = offset
		gConstraints.gridwidth = offset;

		add(getFillerLabel());

		// reset gridwith
		gConstraints.gridwidth = 1;

		head = getDataLabel();
		add(head);

		gConstraints.gridwidth = GridBagConstraints.REMAINDER; // end row

		add(getFillerLabel());

		// ** add tapeLabels-elements ***
		for (int iTape = 0; iTape < tapeCount; iTape++) {
			for (int i = 0; i < 2 * offset + 1; i++) {
				label = getDataLabel();
				tapeLabels[iTape][i] = label;
				if (i == 2 * offset) {
					//end row
					gConstraints.gridwidth = GridBagConstraints.REMAINDER;
				} else{
					// reset gridwith
					gConstraints.gridwidth = 1;
				}
				gLayout.setConstraints(label, gConstraints);
				add(label);
			}
		}
	}
	
	public void update(){
		// set MaschinePanel
		setHead(turingChar.getMaschine().getState());
		char[][] tapes = turingChar.getTapesPart(Factory.OFFSET);
		setTapes(tapes);
	}

	private final void setHead(int head) {
		this.head.setText(Integer.toString(head));
	}

	private final void setTapes(char[][] tapes) {
		for (int iTape = 0; iTape < tapeCount; iTape++) {
			for (int i = 0; i < 2 * offset + 1; i++) {
				tapeLabels[iTape][i].setText(Character
						.toString(tapes[iTape][i]));
			}
		}
	}

	private Label getFillerLabel() {
		Label label = new Label();
		gLayout.setConstraints(label, gConstraints);
		return label;
	}

	private Label getDataLabel() {
		// Label label = new Label("", Label.CENTER);
		// label.setFont(new Font("Courier New", Font.PLAIN, 18));
		// label.setBackground(Color.WHITE);
		Label label = new Label();
		label.setFont(new Font("Courier New", Font.PLAIN, 18));
		label.setBackground(Color.WHITE);
		gLayout.setConstraints(label, gConstraints);
		return label;
	}

}
